package com.edfu.core.testmgt.persistence.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import com.edfu.core.commons.persistence.Sellable;
import com.edfu.core.commons.persistence.entity.CategoryEntity;

@Entity
@Table(name = "test", uniqueConstraints = @UniqueConstraint(columnNames = {"code"}))
public class TestEntity implements ITestMgtEntity, Sellable {
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;
	
	@Column(name = "code", length = 30, nullable = false)
	private String code;
	
	@Column(name = "name", nullable = false)
	private String name;
	
	@Column(name = "logo", nullable = true)
	private String logo;
	
	@Column(name = "description", nullable = true)
	private String description;
	
	@Column(name = "createdBy", nullable = false)
	private String createdBy;
	
	private long createdDate;
	
	private boolean active = true;
	private boolean allowReattempt = true;
	private boolean allowReview = true;
	private boolean allowChangeAnswers = true;
	private boolean timeBased = true;
	
	@Column(columnDefinition = "LONGTEXT")
	private String instructions;
	
//	@ManyToMany(targetEntity = QuestionEntity.class)
	@ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
    @JoinTable(name="test_questions",
                joinColumns={@JoinColumn(name="test_id")},
                inverseJoinColumns={@JoinColumn(name="question_id")})
	private Set<QuestionEntity> questions = new HashSet<QuestionEntity>();
	
	@ManyToOne
	@JoinColumn(name = "test_type_id", nullable = false)
	private TestTypeEntity testType;
	
	/*@ManyToOne
	@JoinColumn(name = "category_id", nullable = false)*/
	@ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
    @JoinTable(name="test_categories",
                joinColumns={@JoinColumn(name="test_id")},
                inverseJoinColumns={@JoinColumn(name="category_id")})
	private Set<CategoryEntity> categories = new HashSet<CategoryEntity>();
	
	@ManyToOne
	@JoinColumn(name = "test_bundle_id", nullable = true)
	private TestBundleEntity testBundle;
	
	private double totalMarks;
	private double positiveMarks;
	private double negativeMarks;
	private double passMarks;
	private long duration;
	
	@Column(name = "price", nullable = true)
    private double price;
    
    @Column(name = "units", nullable = true)
    private String units;
    
    @Column(name = "discType", nullable = true)
    private String discType;
    
    @Column(name = "discValue", nullable = true)
	private double discValue;
    
    @Column(name = "discStart", nullable = true)
	private long discStart;
    
    @Column(name = "discEnd", nullable = true)
	private long discEnd;
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public String getLogo() {
		return logo;
	}
	public void setLogo(String logo) {
		this.logo = logo;
	}
	
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	
	public TestTypeEntity getTestType() {
		return testType;
	}
	public void setTestType(TestTypeEntity testType) {
		this.testType = testType;
	}
	
	public double getTotalMarks() {
		return totalMarks;
	}
	public void setTotalMarks(double totalMarks) {
		this.totalMarks = totalMarks;
	}
	
	public double getPositiveMarks() {
		return positiveMarks;
	}
	public void setPositiveMarks(double positiveMarks) {
		this.positiveMarks = positiveMarks;
	}
	
	public double getNegativeMarks() {
		return negativeMarks;
	}
	public void setNegativeMarks(double negativeMarks) {
		this.negativeMarks = negativeMarks;
	}
	
	public String getCreatedBy() {
		return createdBy;
	}
	public void setCreatedBy(String createdBy) {
		this.createdBy = createdBy;
	}
	
	public long getCreatedDate() {
		return createdDate;
	}
	public void setCreatedDate(long createdDate) {
		this.createdDate = createdDate;
	}
	
	public boolean isActive() {
		return active;
	}
	public void setActive(boolean active) {
		this.active = active;
	}
	
	public Set<QuestionEntity> getQuestions() {
		return questions;
	}
	public void setQuestions(Set<QuestionEntity> questions) {
		this.questions = questions;
	}
	
	public double getPassMarks() {
		return passMarks;
	}
	public void setPassMarks(double passMarks) {
		this.passMarks = passMarks;
	}
	
	public TestBundleEntity getTestBundle() {
		return testBundle;
	}
	public void setTestBundle(TestBundleEntity testBundle) {
		this.testBundle = testBundle;
	}
	
	public long getDuration() {
		return duration;
	}
	public void setDuration(long duration) {
		this.duration = duration;
	}
	
	public boolean isAllowReattempt() {
		return allowReattempt;
	}
	public void setAllowReattempt(boolean allowReattempt) {
		this.allowReattempt = allowReattempt;
	}
	
	public boolean isAllowReview() {
		return allowReview;
	}
	public void setAllowReview(boolean allowReview) {
		this.allowReview = allowReview;
	}
	
	public boolean isAllowChangeAnswers() {
		return allowChangeAnswers;
	}
	public void setAllowChangeAnswers(boolean allowChangeAnswers) {
		this.allowChangeAnswers = allowChangeAnswers;
	}
	
	public boolean isTimeBased() {
		return timeBased;
	}
	public void setTimeBased(boolean timeBased) {
		this.timeBased = timeBased;
	}
	
	public String getInstructions() {
		return instructions;
	}
	public void setInstructions(String instructions) {
		this.instructions = instructions;
	}
	
	public Set<CategoryEntity> getCategories() {
		return categories;
	}
	public void setCategories(Set<CategoryEntity> categories) {
		this.categories = categories;
	}
	
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	
	public String getUnits() {
		return units;
	}
	public void setUnits(String units) {
		this.units = units;
	}
	
	public String getDiscType() {
		return discType;
	}
	public void setDiscType(String discType) {
		this.discType = discType;
	}
	
	public double getDiscValue() {
		return discValue;
	}
	public void setDiscValue(double discValue) {
		this.discValue = discValue;
	}
	
	public long getDiscStart() {
		return discStart;
	}
	public void setDiscStart(long discStart) {
		this.discStart = discStart;
	}
	
	public long getDiscEnd() {
		return discEnd;
	}
	public void setDiscEnd(long discEnd) {
		this.discEnd = discEnd;
	}
	
	@Override
	public String toString() {
		return "TestEntity [code=" + code + ", name=" + name + ", testBundle="
				+ testBundle + "]";
	}	

}
